Skip to content

vk: VRAM, system RAM, GPU and replay CPU time: streams and staging out of VRAM, memory given back when idle, redundant barriers left out, draw setup cached - #585

Closed
BlAnK182C-bak wants to merge 8 commits into
NotRexed:mainfrom
BlAnK182C-bak:vram-streams-staging
Closed

BlAnK182C-bak wants to merge 8 commits into
NotRexed:mainfrom
BlAnK182C-bak:vram-streams-staging

Conversation

@BlAnK182C-bak

@BlAnK182C-bak BlAnK182C-bak commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

vk: VRAM, system RAM, GPU and replay CPU time: streams and staging out of VRAM, memory given back when idle, redundant barriers left out, draw setup cached

Refs #519 (4 GB RTX 3050 Laptop: textures 432 MB (budget 0 MB) with 961 MB of it free in the blocks); likely related: #254, #394.

This PR started with the first four commits (VRAM held by recording streams and staging; part 1 below). It now also carries a second set (part 2): system memory given back when idle, redundant full barriers left out (the GPU-time win), a GPU pass-timing profiler, and an anisotropy override; and a third (part 3): less CPU per draw on the replay thread. Every behaviour change has an env switch back to the old behaviour.


Part 1: ~1 GB of VRAM back on resizable-BAR cards (commits 1-4)

What was using the VRAM

On an RTX 4050 Laptop (6 GB, the driver allows ~5.7 GB) the renderer sat at the driver's limit (VRAM: 5668 MB used of 5708 MB allowed), and the texture budget was squeezed to ~2.0-2.2 GB, while textures (2.2 GB) and mirrors (752 MB) explained only ~3 GB of the ~4.8 GB VMA had allocated. The rest:

What Where VRAM
48 recording streams x 24 MB, created host-visible with UBO/SSBO/index usage draw_begin_recording -> create_buffer(host_visible) 1152 MB + 384 MB left free in their 64 MB blocks (two 24 MB streams a block)
staging arenas kept after loading (4 x 64 MB) staging() 256 MB
guest page table, 24 MB host-visible memory_guest_pages 24 MB (+40 MB free in its block)

With resizable BAR, NVIDIA exposes a DEVICE_LOCAL | HOST_VISIBLE type inside the VRAM heap, and VMA (VMA_MEMORY_USAGE_AUTO + HOST_ACCESS_SEQUENTIAL_WRITE, usage beyond TRANSFER) prefers it, so these CPU-written buffers land in VRAM. The streams' measured peak in Kokiri is ~760 KB of their 24 MB.

Changes

  1. 24 recording slots, not 48, unless submits are batched (RX_VK_RECORDINGS_48=1: 48). The 48 came with RX_VK_BATCH for RADV; 24 was the non-batched count before. Stays 48 with batching or RX_VK_PARALLEL > 1.
  2. Streams and the guest page table get memory objects of their own (RX_VK_BLOCK_BUFFERS=1: shares of 64 MB blocks), so a 24 MB stream no longer leaves 16 MB of a block empty.
  3. The stream's peak is logged, and RX_VK_STREAM_MB=<n> sets its size. Log: vk: the recording streams: N of M MB, the most one held X KB. (Part 2 makes the streams growable, see below.)
  4. On cards of 6 GB or less, idle staging arenas beyond one (64 MB) are given back (RX_VK_STAGING_KEEP_MB=256: as before).

Results (part 1)

Kokiri Forest (Link on his house's balcony), 20 s settle, then 30 s standing and 15 s turning the camera. "Before" and "after" differ only by commits 1-4, measured on a local branch carrying other local changes, identical between the two runs.

before after
texture budget 2049 MB (standing) / 2192 MB (turning) 4036 MB
textures resident 2180 / 2345 MB 2954 / 3027 MB
textures made a frame while turning (evict/remake churn) 4.5 1.3
VRAM, whole GPU (nvidia-smi) 5813 / 5836 MiB 5593 / 5594 MiB
driver-counted use 5668 / 5691 of 5708 MB (at the limit) 5440 of 5701 MB
fps standing / turning 38.7 / 39.9 39.5 / 42.6
frame time median / 99% / worst 25.2 / 37.0 / 108.6 ms 24.7 / 30.2 / 49.2 ms
slow submits / slow presents while turning 19 / 7 8 / 1

Part 2: memory given back when idle, redundant barriers left out (commits 5-7)

GPU time: redundant full barriers left out (on by default, RX_VK_BARRIER_DEDUPE_OFF=1: as before)

  • New gpu/vk/vk_work.h counts GPU work recorded on a command buffer (every work-doing vkCmd* goes through its macros; all files that record work include it). A full barrier that directly follows another on the same command buffer with nothing recorded between them is left out; transfer_barrier goes through the same check. Off while parallel replay is on. The work count is a fetch_add (two threads can record at once).
  • In Kokiri: ~615 full barriers a frame, 192 of them left out (31%). The frame log line: a frame: N full barriers recorded, M left out (nothing recorded since the one before).
  • This is the most correctness-sensitive change in the PR; the switch turns it off.

System RAM and VRAM given back when idle (each on by default, with its switch)

Change Switch back
Recording streams start at 2 MB and grow (moved to a bigger stream when a recording needs it) instead of a fixed 24 MB that skipped draws when full; extra streams are given back after 120 recordings that fit the first RX_VK_STREAM_GROW_OFF=1 (24 MB, skips), RX_VK_STREAM_KEEP=1
Capture buffers in size classes from 2 MB (they were never under 16 MB, for ~1 MB captures: 25 kept ones were 413 MB of resident host-cached memory); dedicated memory from 16 MB; spares capped at 32 MB on cards of 6.5 GB or less RX_VK_CAP_MIN_MB=16, RX_VK_CAP_BLOCKS=1, RX_VK_CAP_SPARE_MB=0
The 160 MB BC3 scratch is made on demand in dedicated memory and given back after 20 s without an upload RX_VK_BC_IDLE_S=0, RX_VK_BC_POOL=1
The texture budget counts what the allocator gave (about 8% more than the texel estimate), so it stops overshooting RX_VK_COUNT_BY_ESTIMATE=1
A replaced TAAU history image is destroyed 120 presents later (it was leaked) RX_VK_TAAU_HIST_LEAK=1
flush_texture reads back into cached host memory, not through the sequential-write buffer RX_VK_FLUSH_UNCACHED=1
Staging arenas nothing staged into for 30 s are given back RX_VK_STAGING_IDLE_S=0
Shadow copies of texture pages no capture took in 256 submits are dropped once they total 32 MB (not only at the 256 MB cap) RX_VK_SHADOW_SWEEP_OFF=1
Linux (glibc): a worker runs malloc_trim(0) when glibc's arenas hold 192 MB free; a vk: malloc: census line every 1800 presents RX_VK_MALLOC_TRIM_MB=0
Knobs, off by default: RX_VK_DESC_POOL_DIV=<n>, RX_VK_IMAGE_BLOCK_MB=<n>, HOS_NO_THP=1 (Linux: transparent huge pages off for the process) -

tests/test_mem_trim.py checks the code keeps what these trims must: what is kept as an offset into a stream names its buffer or reserves its room first (a stream may move mid-recording), every user of the BC3 scratch asks for it first, and capture buffers are sized by class and counted out as well as in.

Diagnostics (off by default)

  • RX_VK_PASS_TIMING=1|2 (alias RX_VK_GPU_PROFILE): GPU timestamps around passes, dispatches, barriers (by origin), copies, mirror syncs and write-backs, reported every 600 presents, with the 25 costliest spans. =2 adds a timestamp per program run inside passes.
  • Every 120 presents: the game's barriers by their NVN flags, and the bytes the GPU read over PCIe from pools bound in guest memory.
  • RX_VK_ANISO=<n>: samplers with linear min and mip filters get at least n-times anisotropy (default 0: the game's own). The game asks for 0-2x. A vk: sampler anisotropy: the game asks for ... line is logged once per distinct value.

Results (part 2)

Same machine and method as part 1, save in Kokiri on Link's balcony, Firefox and Discord closed. Before = a local branch with part 1; after = the same branch plus these commits. Caveat: that local "after" branch also carried three other open PRs' commits (#479, #423, #435), which are not in this PR; with #435 the replay's descriptor time rose ~1 ms (3.35 -> 4.32 ms standing; its bookkeeping found almost nothing to reuse in this game), so the CPU replay figures below understate this PR. The exact branch pushed here has been compiled for Linux x86_64 (all gpu/vk/vk_*.cpp), tests/test_mem_trim.py passes, and a run of this exact branch is still to come; I'll post it as a comment.

before after
fps standing / turning 40.1 / 42.6 44.2 / 45.5 (re-run: 43.4 / 43.4)
GPU time a frame, standing / turning 20.3 / 18.9 ms 17.6 / 15.8 ms (re-run: 17.7 / 16.3)
GPU busy (nvidia-smi) 89 / 90% 86 / 84%
game RSS, standing / turning 10.15 / 9.49 GB 9.22 / 9.17 GB
RSS from smaps_rollup, 10 s into standing 9.79 GB 9.05 GB
Vulkan system-heap allocations 520 MB 151 MB (part of this may be #479's import retiring)
VRAM, whole GPU (nvidia-smi) 5567 / 5557 MiB 5445 / 5610 MiB (more of it holds textures: 3092 / 3635 MB resident vs 2501 / 3279)
CPU (whole process) 333 / 356% 340 / 363% (at ~9% more frames)
frame time median / 99% 24.3 / 31.6 ms 22.2 / 32.6 ms
flashes (frame log, large / all) 4 / 54 2 / 51

Where the GPU frame goes after this PR (RX_VK_PASS_TIMING=1, ~18 ms profiled): render passes 52%, compute dispatches 32%, write-back to guest memory 7% (13 MB a frame), barriers 6%, uploads 8%.

Tried and left out

  • Keeping the open render pass across the game's barrier when its draws stored nothing (~80 a frame qualify): with all of them kept, GPU time went up 2 ms (19.8 / 18.6 ms vs 17.7 / 16.3); with only barriers lacking INVALIDATE_TEXTURE/ORDER_INDIRECT_DATA kept (~3 a frame), no gain. On NVIDIA a barrier inside an open pass costs more than ending and restarting it.
  • No STORAGE usage on COMPRESSIBLE, non-IMAGE textures (so the driver might keep render targets compressed): the game's compute passes write into some of them, so their storage views fail (vk: view of texture ... not made) and the lighting goes wrong (dark, posterized, a black title movie); it was also slower (36 vs 43 fps).

Part 3: less CPU per draw on the replay thread (commit 8)

The replay thread is on the critical path (about 15 ms of a 22 ms frame here, ~2,400 draws). Four places did per draw what the draw before had already done; now they keep it, keyed by exactly what it depends on. Same descriptors, state, banks and programs come out.

Change Switch back
Pushed descriptors kept as one flat vector of words, compared in place (it was a vector of vectors: about a dozen allocations a draw on program changes) RX_VK_PUSH_STATE_OLD=1
Dynamic state's "same as the draw before" check keyed by the program's write-mask signature, not its pointer (every program change recomputed all dynamic state) RX_VK_DYN_PROG_KEY=1
A graphics stage's c0/c2 driver banks kept while their own inputs (texture/sampler/image handles; storage-buffer table) are unchanged, not refilled on every uniform-buffer bind RX_VK_BANK_GEN_OFF=1
The last-program-pick cache survives uniform rebinds for programs whose answers are plain c2 handles RX_VK_PICK_BIND_GEN=1
RX_VK_PROF_FINE=1 (off by default): the draw's time split into finer sections, and what each draw does -

tests/test_push_state.py, test_bank_gen.py, test_pick_tex_gen.py and test_same_dyn.py check the invariants. Program::wm_sig is atomic (replay threads may ask for the same program at once).

Measured so far only as part of a local build that carries these changes with others: the replay thread's time a frame went from ~16.1 ms to ~12.7 ms standing (and fps 43.4 -> 47.8, with the 3D scene at a higher resolution), but that comparison is not isolated (other changes and a different save). An isolated A/B of this exact change (same build, the four switches off vs on) is next; I'll post it as a comment. This branch's commit compiles for Linux x86_64 (all gpu/vk/vk_*.cpp) and its tests pass; it has not been run as this exact branch yet.


Tested on

  • Laptop: Intel Core i7-12650H (6P+4E, 16 threads), 16 GB RAM
  • GPU: NVIDIA GeForce RTX 4050 Laptop GPU, 6 GB (resizable BAR; the driver allows ~5.7 GB), PRIME offload from the Intel UHD iGPU (__NV_PRIME_RENDER_OFFLOAD=1 __VK_LAYER_NV_optimus=NVIDIA_only)
  • Driver: NVIDIA 615.78.08, Vulkan 1.4.351
  • OS: CachyOS, Linux 7.3.0-4-cachyos, KDE Plasma (Wayland)
  • Display: external 2560x1440 @ 144 Hz, game fullscreen at 2560x1440
  • Game settings (Insert menu): Quality preset Custom, Resolution 100%, Upscaling Off, Sharpness 100, Handheld profile Off, Frame generation Off, Frame pacing Off, Game speed Real time
  • Measurement: scripted input (HOS_INPUT_LIVE), the game's 120-frame stat lines, nvidia-smi every 2 s, /proc/<pid>/smaps_rollup, and RX_VK_FRAMELOG + scripts/framelog.py for frame times and flashes.
  • Build: from source (nx2/make_game.py, Linux). This branch is on main 7e9bf73; every changed gpu/vk file compiles for x86_64 Linux.
  • Not tested: Windows, AMD, Intel. Nothing here is Linux-only except malloc_trim and HOS_NO_THP (both under #ifdef __linux__/glibc), but I have not built or run it elsewhere.

🤖 Generated with Claude Code

@BlAnK182C-bak BlAnK182C-bak changed the title vk: ~1 GB of VRAM back on resizable-BAR cards (recording streams and staging held in VRAM) vk: VRAM, system RAM and GPU time: streams and staging out of VRAM, memory given back when idle, redundant barriers left out Nov 8, 2026
@BlAnK182C-bak BlAnK182C-bak changed the title vk: VRAM, system RAM and GPU time: streams and staging out of VRAM, memory given back when idle, redundant barriers left out vk: VRAM, system RAM, GPU and replay CPU time: streams and staging out of VRAM, memory given back when idle, redundant barriers left out, draw setup cached Nov 8, 2026
@shayderrr

Copy link
Copy Markdown
Collaborator

Fix conflicts please

BlAnK182C-bak and others added 8 commits November 9, 2026 00:11
…are batched (RX_VK_RECORDINGS_48=1: 48)

Each recording slot holds a 24 MB stream (vk_draw.cpp: uniform banks, uniform copies, quad indices) made with
VMA_MEMORY_USAGE_AUTO + HOST_ACCESS_SEQUENTIAL_WRITE and uniform/storage/index usage. VMA reads that as "the GPU reads it, the CPU
writes it in order": DEVICE_LOCAL | HOST_VISIBLE preferred, which on an NVIDIA card with resizable BAR (the RTX 4050 Laptop: memory
type 4, in the 6 GB heap) is VRAM. 48 slots, all touched within 8 frames (6 submits a frame), are 1152 MB, and 24 MB in 64 MB blocks
is two to a block: 1536 MB of the card's 5.7 GB held by the streams alone (the low-vram log: 4839 MB allocated = 2450 textures + 752
mirrors + 1152 streams + 256 staging + 160 BC3 scratch + 24 page table + 8; 607 MB free in the blocks, ~420 of it theirs). The
driver's count sat at its limit and squeezed the texture budget to 2318 MB of ~4000.

The 48 came with RX_VK_BATCH (held submits wait for a slot's turn: RADV). Without batching the game waits for the last frame's GPU work
before it submits the next, so ~18 slots at most are in flight and 24 was the number before. Batched submits and a parallel replay
(RX_VK_PARALLEL > 1: a slot a segment) keep 48.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts of their own (RX_VK_BLOCK_BUFFERS=1: shares of 64 MB blocks)

A 24 MB buffer is under half of VMA's 64 MB block (over it VMA goes dedicated by itself), so two fit in a block and 16 MB of it stays
free: with the streams in VRAM (previous commit) 24 blocks of 1536 MB held 1152 MB, and the page table (24 MB) sat in a block of
its own with 40 MB free. Those free bytes are what the log's "N MB of it free in the blocks" counts, and the driver counts them
as the process's. create_buffer takes a `dedicated` flag now; the streams and the page table pass it. Their count of memory objects
(~25) is nothing against the 4096 the driver allows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… line), RX_VK_STREAM_MB=<n> sets its size (24)

The 24 MB per recording was never full in any log (no "stream is full" line), but nothing says how much a recording uses: the banks
c0/c2 (at most 2560 B a stage a draw, repeated ones shared), the c1s, the uniform overlays (57 of up to 64 KB a frame) and the
quad indices. Logged every 3000 recordings (~10 s): the streams made, their size, the most one held. With a peak of a few MB,
RX_VK_STREAM_MB=8 (or 4) takes another 380 MB (or 480) of VRAM off the 24 streams; a recording that overflows skips its quads and
reads null uniforms, so size it by that peak with room.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… are given back (RX_VK_STAGING_KEEP_MB=256: as before)

The staging arenas are create_buffer(TRANSFER_SRC | STORAGE, host visible): STORAGE is device access, so VMA prefers
DEVICE_LOCAL | HOST_VISIBLE for them, and on a card with resizable BAR that is VRAM (the RTX 4050 Laptop's memory type 4, in the 6 GB
heap). The low-vram log: arenas 3 and 4 (288 and 64 MB: a 12288 x 12288 texture's upload at the scene load) were made between
presents 2280 and 2400, and "staging 256 MB in 4 arenas" stands at every 600-frame look after that, with no arena made again:
~nothing is staged in Kokiri gameplay. 192 MB of the 5.7 GB VRAM the texture budget fights for, idle. A scene change that stages
again makes its arenas again (a 64 MB host-visible allocation each); the ones over 64 MB were already given back when idle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h, staging, glibc heap)

- A recording's stream is 2 MB, and a recording that outgrows it moves to a bigger one instead of skipping draws; extra streams are given back after 120 recordings that fit the first (RX_VK_STREAM_GROW_OFF=1: 24 MB and skips; RX_VK_STREAM_KEEP=1: kept).
- A capture's buffer by size class (2 MB up), not 16 MB each; dedicated memory from 16 MB; the spare buffers capped at 32 MB on a card of 6.5 GB or less (RX_VK_CAP_MIN_MB=16, RX_VK_CAP_BLOCKS=1, RX_VK_CAP_SPARE_MB=0: as before).
- The BC3 scratch (160 MB) is made at the first upload that needs it, in memory of its own, and given back after 20 s without one (RX_VK_BC_IDLE_S=0: kept; RX_VK_BC_POOL=1: from the pool).
- The texture budget counts the allocator's size of an image, not its texels (RX_VK_COUNT_BY_ESTIMATE=1: the texels).
- The TAAU stand-in's replaced history image is destroyed 120 presents later (RX_VK_TAAU_HIST_LEAK=1: left).
- flush_texture reads back into cached host memory (RX_VK_FLUSH_UNCACHED=1: the sequential-write buffer).
- Shadow copies of texture pages no capture took in 256 submits are dropped once there are 32 MB of them (RX_VK_SHADOW_SWEEP_OFF=1: only at the 256 MB cap).
- A staging arena nothing has staged into for 30 s is given back, the last one too (RX_VK_STAGING_IDLE_S=0: as before).
- Linux (glibc): malloc_trim(0) on a worker when the arenas hold 192 MB or more free, and a "vk: malloc:" census line, every 1800 presents (RX_VK_MALLOC_TRIM_MB=0: never).
- Knobs, defaults unchanged: RX_VK_DESC_POOL_DIV=<n>, RX_VK_IMAGE_BLOCK_MB=<n>; HOS_NO_THP=1 (Linux: transparent huge pages off for the process).
- tests/test_mem_trim.py: the stream move, the BC3 scratch's users and the capture buffers' counts keep their invariants.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…is left out; RX_VK_PASS_TIMING GPU profile

- vk_work.h counts the GPU work recorded on a command buffer (an atomic add; every work-doing vkCmd goes through its macros). A full barrier right after another one on the same command buffer, nothing recorded between, is left out; the last-barrier state is per thread, and transfer_barrier goes through the same check. Off during parallel replay. RX_VK_BARRIER_DEDUPE_OFF=1: all recorded. The frame log tells the barriers recorded and left out.
- RX_VK_PASS_TIMING=1|2 (alias RX_VK_GPU_PROFILE): GPU timestamps around passes, dispatches, barriers (by origin), copies, mirror syncs and write-backs, both kinds of command buffer summed, reported every 600 presents with the costliest spans; =2 adds one per program run inside passes.
- The frame log counts the game's nvnCommandBufferBarrier calls by their NVN bits, and the 'bound in guest memory, by pool' line adds the bytes of the bindings (what the GPU may read over PCIe).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and mip levels get at least n-times anisotropy (default 0: the game's own); the log tells each anisotropy the game asks for

The sampler's key and its per-slot cache's key carry n, so a cached sampler is never one made for another value. A sampler with a
nearest min filter or mip filter keeps the game's value (a depth-compare sampler too unless it filters that way). n is clamped to the
device's limit (and to 16) and needs samplerAnisotropy. "vk: sampler anisotropy: the game asks for ..." is logged once for each value
(16 at most), to learn what the game sets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e by what the program masks, banks by their bindings' generation, program picks across uniform rebinds

A draw's CPU cost on the replay thread, from four places where most of the work found what the draw before it had found. Same
descriptors, state, banks and programs as before; only what is kept, and what it is kept by, changes.

- Pushed descriptors, one vector of words (RX_VK_PUSH_STATE_OLD=1: the vector of vectors). A program change pushes every write and
  remembers them for the draws after it, which push only the writes that changed. The memory was a vector of vectors resized to each
  program's writes (3 allocations a write grown word by word, the ones cut off freed, a dozen of each a draw), and the changed-only
  path built every write's words into a scratch vector to compare them. Now the words of all writes are in one vector with each
  write's start, built without allocating once grown; a later draw compares each write against its words in place and stores the new
  ones where they differ. Default on: same pushes, same words. tests/test_push_state.py.
- Dynamic state by what the program masks (RX_VK_DYN_PROG_KEY=1: by the program). dynamic_state returns early when the packed inputs
  equal the draw before's, but the pack held the program's pointer (its write masks come from the fragment stage), so every program
  change, most draws, worked the whole state out again. It holds program_wm_sig now: the fragment stage's stored outputs and their
  components, all target_write_mask reads of the program (tests/test_same_dyn.py keeps the two in step). Default on. Program::wm_sig
  is atomic: replay threads may ask for the same program at once.
- Driver banks by the generation of the bindings they are made from (RX_VK_BANK_GEN_OFF=1: by bind_gen). uniform_range kept a stage's
  c0 / c2 bank only while bind_gen stood, and OoT binds a uniform buffer for nearly every draw, so each draw filled the banks of all
  its stages again to find, mostly, the same words. A graphics stage's c2 is made from its texture, sampler and image handles and its
  c0 from its storage buffer table, so NvnState keeps what bind_gen was when each last changed (tex_gen, ssbo_gen per stage) and the
  bank stands while that does. Compute, task and mesh stages stay on bind_gen. A state's generations are made afresh with its
  bind_gen when the replay takes another queue's state. Default on. tests/test_bank_gen.py.
- Program picks across uniform rebinds (RX_VK_PICK_BIND_GEN=1: as before). The pair of last picks in program_for stood only while
  bind_gen did. A graphics program whose every answer is a plain c2 handle (answer_stage_mask: no handle program, no other bank)
  now stands while those stages' tex_gen do; handle programs, compute and task / mesh programs keep bind_gen. The "program picks"
  log line counts the picks taken this way. Default on; builds on the banks' tex_gen. tests/test_pick_tex_gen.py.
- RX_VK_PROF_FINE=1 (diagnostic, off by default; off, each site is a test of one constant): a frame line "a frame (fine)" with the
  descriptor build split into the driver banks, c1, user uniform buffers, storage buffers and textures, and the commands split into
  hazards and the pass, the pipeline bind, the descriptor bind and its push call, the push constants, dynamic state, the vertex and
  index binds and the draw call, in ms a frame; and a second line with what a draw does (descriptors and writes built, bank fills and
  bytes, stream copies, full and changed-only pushes, pipeline binds, dynamic state from the draw before or worked out and its
  commands, vertex and index binds, pipeline keys from the fast pair or the thread's map).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@BlAnK182C-bak

Copy link
Copy Markdown
Contributor Author

@shayderrr rebased and resolved conflicts

NotRexed added a commit that referenced this pull request Nov 8, 2026
vk: VRAM, system RAM, GPU and replay CPU time: streams and staging out of VRAM, memory given back when idle, redundant barriers left out, draw setup cached

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NotRexed added a commit that referenced this pull request Nov 8, 2026
The 24-slot default (RX_VK_RECORDINGS_48) is left out: kRecordings (48) stays the
number of recording slots. The PR's other commits are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@NotRexed NotRexed closed this in de0ae08 Nov 8, 2026
NotRexed added a commit that referenced this pull request Nov 8, 2026
perf(linux): hand guest memory to the GPU as udmabuf dma-bufs, not host pointers

Conflicts with #585 resolved: both include sets kept in host/hos_main.c and
gpu/vk/vk_memory.cpp (the Linux headers before vk_work.h, which goes last).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NotRexed added a commit that referenced this pull request Nov 8, 2026
…counter

#585's DYN_CHANGED counts its calls (FINE_X(FC_DYN_CALLS, 1)): the test's fixture
defines both as nothing, as it stubs the Vulkan commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
madebyjordan added a commit to madebyjordan/Longshot that referenced this pull request Nov 8, 2026
Resolves the conflict with NotRexed#585 (BC3 scratch made on demand, given back
when idle): the second scratch for resized textures now follows the same
lifecycle, made with the first when a resized upload needs it and given
back with it after RX_VK_BC_IDLE_S seconds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@BlAnK182C-bak

Copy link
Copy Markdown
Contributor Author

Hi, @NotRexed was just curious as to why this PR was closed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants